#include "exception.h"

/**输出日志*/
#ifndef HAVE_COLOR_LOG
  #define LOG_I_COLOR ""
  #define LOG_W_COLOR ""
  #define LOG_F_COLOR ""
  #define COLOR_NONE  ""
  #define COLOR_WHITE ""
#else
  #define LOG_I_COLOR "\x1B[1;32m"
  #define LOG_W_COLOR "\x1B[1;33m"
  #define LOG_F_COLOR "\x1B[1;31m"
  #define COLOR_NONE  "\x1B[m"
  #define COLOR_WHITE "\x1B[1;37m"
#endif

#define LOG_I_LEVEL	"INFO "
#define LOG_W_LEVEL	"WARN "
#define LOG_F_LEVEL	"FATAL"

#if GCC_VERSION
  #define BaseName(n)	({ const char *p = strrchr((n), '/'); p ? p + 1 : (n); })
#else
  #define BaseName(n)	(strrchr((n), '\\') ? strrchr((n), '\\') + 1 : (n))
#endif

#if GCC_VERSION
  #define SLogWriteByInfo(level, fmt, ...)							    \
  fprintf(stdout,									    \
	"[" LOG_##level##_COLOR LOG_##level##_LEVEL	    \
	COLOR_WHITE "]|%32s:%04d|%32s()" LOG_##level##_COLOR "|" fmt "\n" COLOR_NONE, \
	BaseName(__FILE__), (__LINE__), (__FUNCTION__), ##__VA_ARGS__)
#else
  #define SLogWriteByInfo(level, fmt, ...)			       \
  STMT_BEGIN						       \
  fprintf(stdout, \
	"[%s]|%32s:%04d|%32s()|", LOG_##level##_LEVEL, \
	BaseName(__FILE__), (__LINE__), (__FUNCTION__)); \
  fprintf(stdout, fmt, ##__VA_ARGS__);	       \
  fprintf(stdout, "\n");			       \
  STMT_END
#endif

const ExceptT EXCEPT_Normal = {
	"Normal Exception.",
	0x01
};

const ExceptT EXCEPT_Skip = {
	"Skip Exception.",
	0x02
};
/*在**内联函数**中不能使用TRY-CATCH-FINALLY模块，但是可以使用RAISE(X)和RERAISE()宏*/
/*可以进行函数之间的跳转的，请自行模拟，这里仅为了表达使用方式*/
int normal_exception()
{
	TRY
	{
		TRY
		{
			TRY
			{
				TRY
				{
					TRY
					{
						TRY
						{
							RAISE(EXCEPT_Normal);
						}
						FINALLY
						{ SLogWriteByInfo(I, "normal stack"); }
						END;
					}
					CATCH
					{ SLogWriteByInfo(I, "normal stack"); RERAISE();}
					END;
				}
				FINALLY
				{ SLogWriteByInfo(I, "normal stack"); }
				END;
			}
			FINALLY
			{ SLogWriteByInfo(I, "normal stack"); }
			END;
		}
		FINALLY
		{ SLogWriteByInfo(I, "normal stack"); }
		END;
	}
	CATCH
	{ SLogWriteByInfo(I, "top stack"); }
	FINALLY
	{ SLogWriteByInfo(I, "%s test has finish", __FUNCTION__);}
	END;
	return EXIT_SUCCESS;
}

int skip_exception()
{
	TRY
	{
		SKIP_TRY
		{
			TRY
			{
				TRY
				{
					TRY
					{
						TRY
						{
							SKIP_RAISE(EXCEPT_Skip);
						}
						FINALLY
						{ SLogWriteByInfo(I, "normal stack"); }
						END;
					}
					CATCH
					{ SLogWriteByInfo(I, "normal stack"); }
					END;
				}
				CATCH
				{ SLogWriteByInfo(I, "normal stack"); }
				END;
			}
			CATCH
			{ SLogWriteByInfo(I, "normal stack"); }
			END;
		}
		CATCH
		{ SLogWriteByInfo(I, "skip stack"); RERAISE(); }
		END;
	}
	CATCH
	{ SLogWriteByInfo(I, "top stack"); }
	FINALLY
	{ SLogWriteByInfo(I, "%s test has finish", __FUNCTION__);}
	END;

	return EXIT_SUCCESS;
}

int main(int argc, char **argv)
{
	if(argc == 1) 
		return normal_exception();
	if(argv[1][0] == 'S' || argv[1][0] == 's' ) 
		return skip_exception();
	return normal_exception();
}
